package first

/*
	地上有一个m行n列的方格，从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动，它每次可以向左、右、上、下移动一格（不能移动到方格外），
	也不能进入行坐标和列坐标的数位之和大于k的格子。例如，当k为18时，机器人能够进入方格 [35, 37] ，因为3+5+3+7=18。但它不能进入方格 [35, 38]，因为3+5+3+8=19。请问该机器人能够到达多少个格子？

	示例 1：
	输入：m = 2, n = 3, k = 1
	输出：3

	示例 2：
	输入：m = 3, n = 1, k = 0
	输出：1
	提示：

	1 <= n,m <= 100
	0 <= k <= 20

	来源：力扣（LeetCode）
	链接：https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof
	著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
*/
func MovingCount(m int, n int, k int) int {
	return movingCount(m, n, k)
}

func movingCount(m int, n int, k int) int {
	dp := make([][]bool, m)
	for i := 0; i < len(dp); i++ {
		dp[i] = make([]bool, n)
	}
	dp[0][0] = true
	ants := 1
	for i := 1; i < m; i++ {
		if dp[i-1][0] && (curSum(i, 0) <= k) {
			dp[i][0] = true
			ants++
		}
	}
	for j := 1; j < n; j++ {
		if dp[0][j-1] && (curSum(0, j) <= k) {
			dp[0][j] = true
			ants++
		}
	}
	for i := 1; i < len(dp); i++ {
		for j := 1; j < len(dp[i]); j++ {
			dp[i][j] = (dp[i-1][j] || dp[i][j-1]) && (curSum(i, j) <= k)
			if dp[i][j] {
				ants++
			}
		}
	}

	return ants
}

func curSum(i int, j int) int {
	result := 0
	for i != 0 {
		result += i % 10
		i /= 10
	}
	for j != 0 {
		result += j % 10
		j /= 10
	}
	return result
}
